/**
 * 使用 librs232 实现的 transceiver
 * 张勇 41204@qq.com
 */

#pragma once

#ifdef __cplusplus

// 用于 C++ 实现

#include "std_err.h"
#include "transceiver.h"

// forward declares
struct rs232_port_t;

class trx_uart: public transceiver {
    public:    static trx_uart* open(const char *addr, size_t mtu, regexp_match_t regexp_match_func = NULL);
    protected: struct rs232_port_t *_rs232 = NULL;
    protected: size_t _mtu = 0;
    protected: trx_uart(const char *addr, size_t mtu, regexp_match_t regexp_match_func = NULL);
    protected: virtual void destroy();
    public:    virtual ~trx_uart() { destroy(); }
    public:    virtual size_t    mtu() override { return _mtu; }
    public:    virtual void      txclear() override;
    public:    virtual void      rxclear() override;
    public:    virtual std_err_t rxwait(long timeout_ms) override;
    public:    virtual std_err_t rxread(void* buf, size_t size, size_t *plen/*out*/) override;
    public:    virtual std_err_t txwrite(const void* buf, uint64_t size, size_t *plen/*out*/) override;
    
    protected: bool _sync_reading = false; ///< 是否正在进行同步(阻塞)的读
    protected: bool _async_thread_exit_flag = false; ///< 异步监听线程退出标志
    protected: unios_thread_t _async_thread = NULL;
    protected: static void async_thread_func(void *cookie);
    public:    std_err_t listen(bool enable) override;
};

/// @brief 用于 C 语言的接口
extern "C" transceiver_t* trx_uart_open(const char *addr, size_t mtu, regexp_match_t regexp_match_func = NULL);

#else

/**
 * 用于 C 语言的接口: 打开使用 librs232 实现的 transceiver
 * @param addr "uart://COM%d,%d,%d,%c,%d", 如 "uart://COM1,115200,8,n,1"
 * @param mtu 缓冲区大小
 * @return transceiver 接口。
 */
transceiver_t* trx_uart_open(const char *addr, size_t mtu, regexp_match_t regexp_match_func);

#endif
